package com.usian.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.usian.admin.feign.ArticleFeign;
import com.usian.admin.feign.WemediaFeign;
import com.usian.admin.service.AdChannelService;
import com.usian.admin.service.AdSensitiveService;
import com.usian.admin.service.WemediaNewsAutoScanService;
import com.usian.common.aliyun.util.GreenImageScan;
import com.usian.common.aliyun.util.GreenTextScan;
import com.usian.common.fastdfs.FastDFSClientUtil;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.admin.pojos.AdChannel;
import com.usian.model.admin.pojos.AdSensitive;
import com.usian.model.article.pojos.ApArticle;
import com.usian.model.article.pojos.ApArticleConfig;
import com.usian.model.article.pojos.ApArticleContent;
import com.usian.model.article.pojos.ApAuthor;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsVo;
import com.usian.utils.common.SensitiveWordUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Autowired
    private WemediaFeign wemediaFeign;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private AdChannelService adChannelService;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private FastDFSClientUtil fastDFSClientUtil;
    @Value("${fileServerUrl}")
    private String fileServerUrl;
    @Autowired
    private AdSensitiveService adSensitiveService;

    @GlobalTransactional
    public void newAutoScan(Integer id) {
        //1.校验参数，获取要审核的文章对象
        if(id==null){
            return;
        }
        WmNews wmNews = wemediaFeign.findByNewId(id);
        if (wmNews==null){
            return;
        }
        Long articleId=null;
        //2.根据文章不同的状态决定是否要审核
        if (wmNews.getStatus()==4){
            //4:人工审核通过
            articleId=this.saveArticle(wmNews);
        }
        if (wmNews.getStatus()==8 && wmNews.getPublishTime().getTime()<=System.currentTimeMillis()){
            //8:审核通过，待发布
            articleId=this.saveArticle(wmNews);
        }

        //3.审核 阿里云内容安全接口 敏感词
        if (wmNews.getStatus()==1){
            //审核文本 --阿里云
            Map<String, Object> map = this.handleTextImages(wmNews);
            String textStr =(String) map.get("content");
            boolean textScan = this.handleTextScan(textStr, wmNews);
            if (!textScan){
                return;
            }
            //审核图片 --阿里云
            List<String> imageList = (List<String>) map.get("images");
            boolean imageScan = this.handleImagesScan(imageList, wmNews);
            if (!imageScan){
                return;
            }
            //审核敏感词
            boolean handleSenSitive = this.handleSenSitive(textStr, wmNews);
            if (!handleSenSitive){
                return;
            }
            //5.wmnews -->  ap_article  ap_article_config ap_article_content
            articleId=this.saveArticle(wmNews);
        }
        //4.修改wmnews status  8/9
        wmNews.setArticleId(articleId);

        if(wmNews.getPublishTime().getTime()>System.currentTimeMillis()){
            this.updateWmnewStatus(wmNews,(short)8,"审核通过，待发布");
        }else {
            this.updateWmnewStatus(wmNews,(short)9,"审核通过，已发布");
        }


    }



    private boolean handleSenSitive(String content,WmNews wmNews){
        boolean flag=false;
        List<AdSensitive> sensitiveList = adSensitiveService.findAllSensitive();

        List<String> sensitiveListStr=new ArrayList<>();
        for (AdSensitive adSensitive : sensitiveList) {
            sensitiveListStr.add(adSensitive.getSensitives());
        }
        SensitiveWordUtil.initMap(sensitiveListStr);

        Map<String, Integer> words = SensitiveWordUtil.matchWords(content);
        if (words.size()==0){
            //包含敏感词，审核通过
            flag=true;
        }else {
            //不通过
            this.updateWmnewStatus(wmNews,(short)2,"内容中包含敏感词");
        }
        return flag;
    }

    private Map<String,Object> handleTextImages(WmNews wmNews){
        String content = wmNews.getContent();
        StringBuilder stringBuilder=new StringBuilder();
        List<String> imageList=new ArrayList<>();

        List<Map> list = JSON.parseArray(content, Map.class);
        //分离内容图片
        for (Map map : list) {
            if (map.get("type").equals("text")){
                stringBuilder.append(map.get("value"));
            }
            if (map.get("type").equals("image")){
                imageList.add(map.get("value").toString());
            }
        }
        //分离封面的图片
        if (wmNews.getImages()!=null && wmNews.getType()>0){
            String[] strings = wmNews.getImages().split(",");
            imageList.addAll(Arrays.asList(strings));
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("content", stringBuilder.toString());
        resultMap.put("images", imageList);
        return resultMap;
    }

    private boolean handleImagesScan(List<String> images, WmNews wmNews){
        if (images == null) {
            return true;
        }
        boolean flag = false;

            try {
                List<byte[]> imageList=new ArrayList<>();
                for (String image : images) {
                    //http://192.168.1.153/group/M00/1/2/111.jpg
                    String replace = image.replace(fileServerUrl, "");
                    //group/M00/1/2/111.jpg
                    String groupName = replace.substring(0, replace.indexOf("/"));
                    String groupPath = replace.substring(replace.indexOf("/") + 1);
                    byte[] bytes = fastDFSClientUtil.download(groupName, groupPath);
                    imageList.add(bytes);
                }
                    Map map = greenImageScan.imageScan(imageList);
                    if (!map.get("suggestion").equals("pass")){
                    // block review
                    if (map.get("suggestion").equals("block")){
                        this.updateWmnewStatus(wmNews,(short)2,"图片审核不通过");
                    }
                    if (map.get("suggestion").equals("review")){
                        this.updateWmnewStatus(wmNews,(short)3,"图片审核不确定，建议人工审核");
                    }
                }else {
                    flag=true;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return flag;
    }


    private boolean handleTextScan(String content,WmNews wmNews){
        boolean flag=false;
        try {
            Map map = greenTextScan.greeTextScan(content);
            if (!map.get("suggestion").equals("pass")){
                // block review
                if (map.get("suggestion").equals("block")){
                    this.updateWmnewStatus(wmNews,(short)2,"文本审核不通过");
                }
                if (map.get("suggestion").equals("review")){
                    this.updateWmnewStatus(wmNews,(short)3,"文本审核不确定，建议人工审核");
                }
            }else {
                flag=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    private void updateWmnewStatus(WmNews wmNews,Short status,String msg){
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        wemediaFeign.UpdateNewStatus(wmNews);
    }

    private Long saveArticle(WmNews wmNews){
        //ap_article  ap_article_config ap_article_content
        ApArticle apArticle = new ApArticle();
        apArticle.setTitle(wmNews.getTitle());
        apArticle.setLayout(wmNews.getType());
        apArticle.setImages(wmNews.getImages());
        apArticle.setCreatedTime(new Date());

        Integer userId = wmNews.getUserId();
        ApAuthor apAuthor = articleFeign.findByWmUserId(userId);
        if (apAuthor!=null){
            apArticle.setAuthorId(Long.valueOf(apAuthor.getId()));
            apArticle.setAuthorName(apAuthor.getName());
        }

        Integer channelId = wmNews.getChannelId();
        AdChannel adChannel = adChannelService.getById(channelId);
        if (adChannel!=null){
            apArticle.setChannelId(channelId);
            apArticle.setChannelName(adChannel.getName());
        }
        ApArticle apArticle1 = articleFeign.saveApArticle(apArticle);

        //2
        ApArticleContent apArticleContent=new ApArticleContent();
        apArticleContent.setArticleId(apArticle1.getId());
        apArticleContent.setContent(wmNews.getContent());
        ApArticleContent apArticleContent1 = articleFeign.saveApArticleContent(apArticleContent);

        //3：
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticle1.getId());
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsDelete(false);
        apArticleConfig.setIsDown(true);
        apArticleConfig.setIsComment(true);
        ApArticleConfig apArticleConfig1 = articleFeign.saveApArticleConfig(apArticleConfig);

        return apArticle1.getId();
    }

    @Override
    public ResponseResult findNews(NewsAuthDto dto) {
        ResponseResult list = wemediaFeign.findList(dto);
        list.setHost(fileServerUrl);
        return list;
    }

    @Override
    public ResponseResult findNewsById(Integer id) {
        if (id==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNewsVo wmNewsVo = wemediaFeign.findNewsById(id);
        return ResponseResult.okResult(wmNewsVo);
    }

    @Override
    public ResponseResult authPass(NewsAuthDto dto) {
        if (dto==null && dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = wemediaFeign.findByNewId(dto.getId());

        this.updateWmnewStatus(wmNews,(short)4,"人工审核通过");
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult authFail(NewsAuthDto dto) {
        if (dto==null && dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = wemediaFeign.findByNewId(dto.getId());

        this.updateWmnewStatus(wmNews,(short)2,"人工审核失败");
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
